//
// Created by hkkzzxz on 24-9-1.
//

#include "RedisDatabaseModel.h"
#include "RedisConnectionPool.h"

bool RedisDatabaseModel::set(const std::string &key, const std::string &value) {
    RedisConnectionPool *pool = RedisConnectionPool::getInstance();
    auto redisConn = pool->getConnection();
    redisReply *reply = (redisReply *) redisCommand(redisConn.get(), "SET %s %s", key.c_str(), value.c_str());
    if (reply == NULL) {
        consoleLogger->warn("Redis failed to set");
        fileLogger->warn("Redis failed to set");
        pool->releaseConnection(redisConn);
        freeReplyObject(reply);
        return false;
    }
    consoleLogger->info("redis set: {}", reply->str);

    pool->releaseConnection(redisConn);
    freeReplyObject(reply);
    return true;
}

std::string RedisDatabaseModel::get(const std::string &key) {
    RedisConnectionPool *pool = RedisConnectionPool::getInstance();
    auto redisConn = pool->getConnection();
    redisReply *reply = (redisReply *) redisCommand(redisConn.get(), "GET %s", key.c_str());
    if (reply == NULL) {
        consoleLogger->warn("Redis failed to get");
        fileLogger->warn("Redis failed to get");
        pool->releaseConnection(redisConn);
        freeReplyObject(reply);
        return "";
    }
    consoleLogger->info("redis get: {}", reply->str);
    std::string result = reply->type == REDIS_REPLY_STRING ? std::string(reply->str) : "";
    pool->releaseConnection(redisConn);
    freeReplyObject(reply);
    return result;
}

bool RedisDatabaseModel::del(const std::string &key) {
    RedisConnectionPool *pool = RedisConnectionPool::getInstance();
    auto redisConn = pool->getConnection();
    redisReply *reply = (redisReply *) redisCommand(redisConn.get(), "DEL %s", key.c_str());
    if (reply == NULL) {
        consoleLogger->warn("Redis failed to delete");
        fileLogger->warn("Redis failed to delete");
        pool->releaseConnection(redisConn);
        freeReplyObject(reply);
        return false;
    }
    pool->releaseConnection(redisConn);
    freeReplyObject(reply);
    return true;
}

bool RedisDatabaseModel::exists(const std::string &key) {
    RedisConnectionPool *pool = RedisConnectionPool::getInstance();
    auto redisConn = pool->getConnection();
    redisReply *reply = (redisReply *) redisCommand(redisConn.get(), "EXISTS %s", key.c_str());
    if (reply == NULL) {
        consoleLogger->warn("Redis failed to check existence of key");
        fileLogger->warn("Redis failed to check existence of key");
        pool->releaseConnection(redisConn);
        freeReplyObject(reply);
        return false;
    }
    
    bool keyExists = (reply->integer == 1);
    pool->releaseConnection(redisConn);
    freeReplyObject(reply);
    return keyExists;
}
